home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
util
/
misc
/
zkick301.lzh
/
romtag.asm
< prev
next >
Wrap
Assembly Source File
|
1991-07-10
|
11KB
|
572 lines
*
* ZKick V3.01 -- Copyright (C) 1991 by Daniel Zenchelsky
*
* This program may be freely copied, as long as all copyright
* notices are left intact and unchanged.
*
SECTION code
NOLIST
INCLUDE "exec/types.i"
INCLUDE "exec/initializers.i"
INCLUDE "exec/libraries.i"
INCLUDE "exec/lists.i"
INCLUDE "exec/alerts.i"
INCLUDE "exec/resident.i"
INCLUDE "exec/memory.i"
INCLUDE "exec/tasks.i"
INCLUDE "exec/execbase.i"
INCLUDE "libraries/expansion.i"
INCLUDE "zkick.i"
INCLUDE "mmu.i"
LIST
XDEF Reboot
XDEF _MakeRomTag
XDEF _config
XDEF _connum
XDEF _memory
XDEF _memnum
XDEF _Survive
XDEF _MMU
XDEF _NOMMU
XDEF _NOCHECKSUM
XDEF _NORESET
XDEF _DEBUG
XDEF _PRINT
XDEF _LOADC0
XDEF _V175
XDEF _StartKick
;------ These don't have to be external, but it helps some
;------ debuggers to have them globally visible
XDEF modName
XDEF MemName
XDEF _InitRoutine
XDEF initDDescrip
XDEF ABSEXECBASE
XDEF SaveMem
XDEF KickMem
XDEF KickTag
XDEF expansionname
XDEF ExpansionBase
XDEF ConfigCopy
XDEF AddMem
XDEF EndTag
XDEF CheckSum
XREF _LVOSumKickData
XREF _LVOOpenLibrary
XREF _LVOCloseLibrary
XREF _LVOAddConfigDev
XREF _LVOAllocConfigDev
XREF _LVOCopyMem
XREF _LVOAddMemList
XREF _LVOSetFunction
XREF _LVOSuperState
XREF _LVOSupervisor
XREF _LVODisable
;
; Offsets from ExecBase
;
*KickMemPtr EQU $222
*KickTagPtr EQU $226
*KickCheckSum EQU $22a
*WarmCapture EQU 50
*CoolCapture EQU 46
*ColdCapture EQU 42
ExecVersion EQU $14
ROMVersion EQU $FC0010
VERSION: EQU 3
REVISION: EQU 01
_MakeRomTag:
move.l ABSEXECBASE,a6
;
; Set up KickMemPtr
;
lea.l KickMem+14,a0
move.w #1,(a0)+ ; Number of Entries = 1
lea.l SaveMem,a1
move.l a1,(a0)+ ; Allocation Start
lea.l EndTag-SaveMem,a1 ; Allocation Length
move.l a1,(a0)+
lea.l KickMem,a0
move.l KickMemPtr(a6),(a0) ; old pointer in ln_Succ
move.l a0,KickMemPtr(a6)
;
; Set up KickTagPtr
;
lea KickTag,a0
move.l KickTagPtr(a6),4(a0) ; Old pointer at the end of the table
beq.s .nomore
bset.b #7,4(a0) ; Bit 31 = Extend table
.nomore:
move.l a0,KickTagPtr(a6)
;
; Calculate checksum
;
jsr _LVOSumKickData(a6)
move.l d0,KickCheckSum(a6)
;
; Setup reboot code
;
jsr SetVectors
rts
;-----------------------------------------------------------------------
; From here on is protected from erasure during reboot
;-----------------------------------------------------------------------
SaveMem:
KickMem:
DC.L 0,0,0,0,0,0
KickTag:
DC.L initDDescrip
DC.L $0
_StartKick: DC.L $00000000
OldAddMemList: DC.L $00000000
_Survive: DC.L $00000000
_MMU: DC.L $00000000
_NOMMU: DC.L $00000000
_NOCHECKSUM: DC.L $00000000
_NORESET: DC.L $00000000
_DEBUG: DC.L $00000000
_PRINT: DC.L $00000000
_LOADC0: DC.L $00000000
_V175: DC.L $00000000
;
; --- ColdReboot()
;
XREF _LVOSupervisor
MAGIC_ROMEND EQU $01000000 ;End of Kickstart ROM
MAGIC_SIZEOFFSET EQU -$14 ;Offset from end of ROM to Kickstart size
V36_EXEC EQU 36 ;Exec with the ColdReboot() function
TEMP_ColdReboot EQU -726 ;Offset of the V36 ColdReboot function
_ColdReboot: move.l ABSEXECBASE,a6
cmp.w #V36_EXEC,LIB_VERSION(a6)
blt.s old_exec
jmp TEMP_ColdReboot(a6) ;Let Exec do it...
;NOTE: Control flow never returns to here
;---- manually reset the Amiga ---------------------------------------------
old_exec: lea.l GoAway(pc),a5 ;address of code to execute
jsr _LVOSupervisor(a6) ;trap to code at (a5)...
;NOTE: Control flow never returns to here
;-------------- MagicResetCode ---------DO NOT CHANGE-----------------------
CNOP 0,4 ;IMPORTANT! Longword align!
GoAway: lea.l MAGIC_ROMEND,a0 ;(end of ROM)
sub.l MAGIC_SIZEOFFSET(a0),a0 ;(end of ROM)-(ROM size)=PC
move.l 4(a0),a0 ;Get Initial Program Counter
subq.l #2,a0 ;now points to second RESET
reset ;first RESET instruction
jmp (a0) ;CPU Prefetch executes this
;NOTE: the RESET and JMP instructions must share a longword!
;---------------------------------------DO NOT CHANGE-----------------------
;
; Set up the reboot routines
;
SetVectors:
PUTMSG <'SetVectors'>
tst.l _LOADC0
beq.s 1$
move.l #0,MaxExtMem(a6)
1$: lea.l ColdRoutine,a0
move.l a0,ColdCapture(a6)
lea.l CoolRoutine,a0
move.l a0,CoolCapture(a6)
; Recalculate checksum
lea $22(a6),a0
moveq #$16,d0
moveq #0,d1
sumloop:
add.w (a0)+,d1
dbra d0,sumloop
not.w d1
move.w d1,$52(a6)
rts
tmp: dc.l 0
ColdRoutine:
NS_PUTMSG <'ColdRoutine'>
move.l a5,tmp ; We can't test ExecBase because 1.3
; will use the 2.0 ExecBase.
and.w #$FFF0,tmp ; So we look at the return address
cmp.w #$00F0,tmp ; to see if we are running from ROM.
; <-- Should check for $F80000-$FFFFFF
bne DoneCold
NS_PUTMSG <'Version 1.2/1.3 ColdCapture'>
cmp.l #-$1,d6 ; Test to see if there is a delayed GURU
beq NoGuru ; If not, skip this.
move.l #$48454C50,0 ; move "HELP" to location 0
; KickStart 2.0 will take care of the rest
NoGuru:
cmp.l #$B7FC0004,$1e(a5) ; Verify that this is really 1.2/1.3
bne.s skipfix
move.l $3E(A6),A3 ; Skip version and >512k chip mem
jmp $1e(a5) ; checks
skipfix:
NS_PUTMSG <'skipfix'>
DoneCold:
jmp (a5)
CoolRoutine:
PUTMSG <'CoolRoutine'>
movem.l a0-a6/d0-d7,-(SP)
move.l ABSEXECBASE,a6
move.w ROMVersion,a0 ; If we're running under 2.0
cmp.w ExecVersion(a6),a0 ; skip this.
bne.s DoneCool
PUTMSG <'Version 1.2/1.3 CoolCapture'>
movea.l a6,a1 ; Keep exec 1.2/1.3 from stomping
lea.l NewAddMemList,a0 ; on the first few bytes
move.l a0,d0 ; of kickstart memory.
lea.l _LVOAddMemList,a0
jsr _LVOSetFunction(a6)
move.l d0,OldAddMemList
DoneCool:
movem.l (SP)+,a0-a6/d0-d7
rts
NewAddMemList:
PUTMSG <'NewAddMemList'>
rts
;-----------------------------------------------------------------------
; A romtag structure. Both "exec" and "ramlib" look for
; this structure to discover magic constants about you
; (such as where to start running you from...).
;-----------------------------------------------------------------------
; Most people will not need a priority and should leave it at zero.
; the RT_PRI field is used for _configuring the roms. Use "mods" from
; wack to look at the other romtags in the system
MYPRI EQU 107
initDDescrip:
;STRUCTURE RT,0
DC.W RTC_MATCHWORD ; UWORD RT_MATCHWORD
DC.L initDDescrip ; APTR RT_MATCHTAG
DC.L EndTag ; APTR RT_ENDSKIP
DC.B RTF_COLDSTART ; UBYTE RT_FLAGS
DC.B VERSION ; UBYTE RT_VERSION
DC.B NT_UNKNOWN ; UBYTE RT_TYPE
DC.B MYPRI ; BYTE RT_PRI
DC.L modName ; APTR RT_NAME
DC.L idString ; APTR RT_IDSTRING
DC.L _InitRoutine ; APTR RT_INIT
; this is the name that the module will have
modName: DC.B 'zkick.romtag',0
idString: dc.b 'zkick.romtag 3.01 (7/10/91)',13,10,0
MemName: dc.b 'zkick memory',0
expansionname: dc.b 'expansion.library',0
CNOP 0,4
ABSEXECBASE EQU $00000004
ExpansionBase: DC.L $00000000
ConfigCopy: DC.L $00000000
_InitRoutine:
movem.l d0-d7/a0-a6,-(a7)
PUTMSG <'InitRoutine'>
move.l ABSEXECBASE,a6 ; If we're running under 1.2/1.3
move.l ROMVersion,a0 ; we wan't to start KickStart
cmp.l ExecVersion(a6),a0 ; from _StartKick
bne okversion
tst.l _NOCHECKSUM
bne.s skipsum
move.l _StartKick,a0 ; Checksum KickStart image
move.l #$80000,d1 ; at _StartKick
jsr CheckSum
tst.l d0
bne panic
PUTMSG <'KickStart Checksum valid'>
skipsum:
; Let's be doubly cautious:
jsr _LVOSuperState(a6)
move.l _StartKick,a0 ; Verify that there's a
; KickStart image at
cmp.w #$4ef9,2(a0) ; _StartKick
bne panic
PUTMSG <'KickStart checks out OK'>
tst.l _NOMMU
bne.s 1$
move.l ABSEXECBASE,a6 ; If there is an MMU
jsr _LVODisable(a6) ; disable it before
tst.l _MMU ; starting KickStart
beq 1$
move.l #0,a0
jsr SetTC
1$:
PUTMSG <'Jumping to KickStart'>
move.l _StartKick,A0
move.l 4(A0),A0
jmp (A0) ; Start KickStart
panic: ; Uh oh, doesn't look like
; KickStart at _StartKick
PUTMSG <'panic!'>
clr.l ColdCapture(a6)
clr.l CoolCapture(a6)
clr.l WarmCapture(a6) ; Clear vectors and reboot
clr.l KickTagPtr(a6)
clr.l KickMemPtr(a6)
jmp Reboot
okversion:
PUTMSG <'okversion'>
tst.l _Survive ; Do we want to survive?
beq.s 2$
jsr SetVectors ; Set up Capture vectors
; for reboot survival
2$: lea.l expansionname,A1
clr.l D0
jsr _LVOOpenLibrary(a6) ; Open expansion.library
move.l D0,ExpansionBase
tst.l D0
bne.s 1$
jmp exit
1$:
lea.l _config,a2
move.l _connum,a3
PUTMSG <'Adding expansion devices'>
loop:
cmp.l #0,a3
beq close
move.l ExpansionBase,a6 ; For each configdev structure we
jsr _LVOAllocConfigDev(a6) ; saved, allocate a fresh configdev
move.l D0,ConfigCopy ; structure.
tst.l D0
bne.s 2$
jmp close
2$:
move.l a2,A0
move.l ConfigCopy,A1 ; Copy the old configdev onto
move.l #end_config-_config,D0 ; the new one
move.l ABSEXECBASE,a6
jsr _LVOCopyMem(a6)
move.l ConfigCopy,A0
move.l ExpansionBase,a6
jsr _LVOAddConfigDev(a6) ; Add it to the configdev list
PUTMSG <'Linked 1 ConfigDev'>
subq.l #1,a3
add.l #end_config-_config,a2 ; Go get another configdev structure
jmp loop
close:
move.l ExpansionBase,A1
move.l ABSEXECBASE,a6 ; Close expansion.library
jsr _LVOCloseLibrary(a6)
AddMem:
PUTMSG <'Adding Memory'>
lea _memory,a2 ; Do the same thing
move.l _memnum,a3 ; for the memory lists
AddMemLoop:
cmp.l #0,a3
beq.s exit
move.l (a2),a0
addq.l #4,a2
move.l (a2),d0
addq.l #4,a2
move.l #MEMF_FAST+MEMF_PUBLIC,d1
clr.l d2
lea.l MemName,a1
move.l ABSEXECBASE,a6
jsr _LVOAddMemList(a6)
PUTMSG <'Linked 1 mem board'>
subq.l #1,a3
jmp AddMemLoop
exit:
movem.l (a7)+,d0-d7/a0-a6
rts
CheckSum:
PUTMSG <'CheckSum'>
lsr.l #2,d1
subq.l #1,d1
moveq #0,d0
1$: add.l (a0)+,d0
bcc.s 2$
addq.l #1,d0
2$: dbra d1,1$
sub.l #$10000,d1
bpl.s 1$
addq.l #1,d0
rts
;======================================================================
;
; This function sets the MMU TC register. It assumes a 68020
; system with MMU, or a 68030 based system (eg, test for MMU before
; you call this, or you wind up in The Guru Zone).
;
; SetTC(ULONG)
; a0
;======================================================================
SetTC:
PUTMSG <'SetTC'>
move.l 4,a6 ; Get ExecBase
move.l a5,-(sp)
lea.l 1$,a5 ; Get the start of the supervisor code
CALLSYS Supervisor
move.l (sp)+,a5
rts
1$
_PMOVE a0,tc ; Just set the TC register
; Was _PMOVE (a0),tc <-- Looked wrong!
rte
Reboot:
PUTMSG <'Reboot'>
tst.l _NOMMU
bne.s nommu
PUTMSG <'Disabling MMU'>
move.l ABSEXECBASE,a6 ; If there is an MMU,
jsr _LVODisable(a6) ; disable it before
tst.l _MMU ; rebooting.
beq nommu
move.l #0,a0
jsr SetTC
nommu:
jmp _ColdReboot
EndCode:
*********
CNOP 0,4 ; LongWord Align (For CopyMem)
_connum:
DS.L 1
_config:
DS.L 17
end_config:
DS.L 17*7
_memnum:
DS.L 1
_memory:
DS.L 2
end_memory:
DS.L 2*7
EndTag:
END